package com.zlyx.easy.security.authentication.handler;

import java.io.IOException;
import java.util.HashMap;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.util.OAuth2Utils;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.OAuth2Request;
import org.springframework.security.oauth2.provider.TokenRequest;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestValidator;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import com.zlyx.easy.core.jackson.JSONObject;
import com.zlyx.easy.core.utils.ResponseUtils;
import com.zlyx.easy.core.utils.StringUtils;
import com.zlyx.easy.security.authentication.service.IClientDetailsService;

/**
 * <p>
 * 登录成功回调
 * </p>
 *
 * @author zhaog
 * @version v1.0
 */
public class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

	protected Logger logger = LoggerFactory.getLogger(AuthenticationSuccessHandler.class);

	@Lazy
	@Autowired
	protected AuthorizationServerTokenServices authorizationServerTokenServices;

	@Autowired(required = false)
	protected IClientDetailsService clientDetailsService;

	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {
		String clientId = request.getParameter(OAuth2Utils.CLIENT_ID);
		String grantType = request.getParameter(OAuth2Utils.GRANT_TYPE);
		if (StringUtils.isBlank(clientId)) {
			throw new ServletException("client_id is null");
		}
		ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
		if (clientDetails == null) {
			throw new ServletException("client_id is invalid");
		}
		TokenRequest tokenRequest = new TokenRequest(new HashMap<>(), clientId, clientDetails.getScope(), grantType);
		// 校验scope
		new DefaultOAuth2RequestValidator().validateScope(tokenRequest, clientDetails);

		// 创建token
		OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
		OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);
		OAuth2AccessToken oAuth2AccessToken = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);

		write(clientId, response, oAuth2AccessToken);
	}

	/**
	 * 返回
	 * 
	 * @param clientId          客户端id
	 * @param response          响应
	 * @param oAuth2AccessToken token
	 * @throws IOException
	 */
	public void write(String clientId, HttpServletResponse response, OAuth2AccessToken oAuth2AccessToken)
			throws IOException {
		logger.info("oAuth2AccessToken.{}", JSONObject.toJSONString(oAuth2AccessToken));
		ResponseUtils.write(response, oAuth2AccessToken);
	}
}
